/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.bpm.engine;

import com.je.bpm.core.model.FlowNode;
import com.je.bpm.core.model.task.KaiteBaseUserTask;
import com.je.bpm.engine.delegate.event.ActivitiCountersignedOpinionType;
import com.je.bpm.engine.impl.persistence.entity.TaskEntity;
import com.je.bpm.engine.impl.persistence.entity.VariableInstance;
import com.je.bpm.engine.internal.Internal;
import com.je.bpm.engine.runtime.DataObject;
import com.je.bpm.engine.task.*;

import java.io.InputStream;
import java.util.*;

/**
 * Service which provides access to {@link Task} and form related operations.
 * 任务Service，用于管理，查询任务，例如：签收，办理，指派等
 */
@Internal
public interface TaskService {

    /**
     * Creates a new task that is not related to any process instance.
     * <p>
     * The returned task is transient and must be saved with {@link #saveTask(Task)} 'manually'.
     */
    Task newTask();

    /**
     * create a new task with a user defined task id
     */
    Task newTask(String taskId);

    /**
     * Saves the given task to the persistent data store. If the task is already present in the persistent store, it is updated. After a new task has been saved, the task instance passed into this
     * method is updated with the id of the newly created task.
     *
     * @param task the task, cannot be null.
     */
    Task saveTask(Task task);

    /**
     * Deletes the given task, not deleting historic information that is related to this task.
     *
     * @param taskId The id of the task that will be deleted, cannot be null. If no task exists with the given taskId, the operation is ignored.
     * @throws ActivitiObjectNotFoundException when the task with given id does not exist.
     * @throws ActivitiException               when an error occurs while deleting the task or in case the task is part of a running process.
     */
    void deleteTask(String taskId);

    /**
     * Deletes all tasks of the given collection, not deleting historic information that is related to these tasks.
     *
     * @param taskIds The id's of the tasks that will be deleted, cannot be null. All id's in the list that don't have an existing task will be ignored.
     * @throws ActivitiObjectNotFoundException when one of the task does not exist.
     * @throws ActivitiException               when an error occurs while deleting the tasks or in case one of the tasks is part of a running process.
     */
    void deleteTasks(Collection<String> taskIds);

    /**
     * Deletes the given task.
     *
     * @param taskId  The id of the task that will be deleted, cannot be null. If no task exists with the given taskId, the operation is ignored.
     * @param cascade If cascade is true, also the historic information related to this task is deleted.
     * @throws ActivitiObjectNotFoundException when the task with given id does not exist.
     * @throws ActivitiException               when an error occurs while deleting the task or in case the task is part of a running process.
     */
    void deleteTask(String taskId, boolean cascade);

    /**
     * Deletes all tasks of the given collection.
     *
     * @param taskIds The id's of the tasks that will be deleted, cannot be null. All id's in the list that don't have an existing task will be ignored.
     * @param cascade If cascade is true, also the historic information related to this task is deleted.
     * @throws ActivitiObjectNotFoundException when one of the tasks does not exist.
     * @throws ActivitiException               when an error occurs while deleting the tasks or in case one of the tasks is part of a running process.
     */
    void deleteTasks(Collection<String> taskIds, boolean cascade);

    /**
     * Deletes the given task, not deleting historic information that is related to this task..
     *
     * @param taskId       The id of the task that will be deleted, cannot be null. If no task exists with the given taskId, the operation is ignored.
     * @param deleteReason reason the task is deleted. Is recorded in history, if enabled.
     * @throws ActivitiObjectNotFoundException when the task with given id does not exist.
     * @throws ActivitiException               when an error occurs while deleting the task or in case the task is part of a running process
     */
    void deleteTask(String taskId, String deleteReason);

    /**
     * Deletes the given task, not deleting historic information that is related to this task..
     *
     * @param taskId       The id of the task that will be deleted, cannot be null. If no task exists with the given taskId, the operation is ignored.
     * @param deleteReason reason the task is deleted. Is recorded in history, if enabled.
     * @param cancel       mark the task as cancelled
     * @throws ActivitiObjectNotFoundException when the task with given id does not exist.
     * @throws ActivitiException               when an error occurs while deleting the task or in case the task is part of a running process
     */
    void deleteTask(String taskId, String deleteReason, boolean cancel);

    /**
     * Deletes all tasks of the given collection, not deleting historic information that is related to these tasks.
     *
     * @param taskIds      The id's of the tasks that will be deleted, cannot be null. All id's in the list that don't have an existing task will be ignored.
     * @param deleteReason reason the task is deleted. Is recorded in history, if enabled.
     * @throws ActivitiObjectNotFoundException when one of the tasks does not exist.
     * @throws ActivitiException               when an error occurs while deleting the tasks or in case one of the tasks is part of a running process.
     */
    void deleteTasks(Collection<String> taskIds, String deleteReason);

    /**
     * Deletes all tasks of the given collection, not deleting historic information that is related to these tasks.
     *
     * @param taskIds      The id's of the tasks that will be deleted, cannot be null. All id's in the list that don't have an existing task will be ignored.
     * @param deleteReason reason the task is deleted. Is recorded in history, if enabled.
     * @throws ActivitiObjectNotFoundException when one of the tasks does not exist.
     * @throws ActivitiException               when an error occurs while deleting the tasks or in case one of the tasks is part of a running process.
     * @oaramn cancel
     * mark the task as cancelled
     */
    void deleteTasks(Collection<String> taskIds, String deleteReason, boolean cancel);

    /**
     * Claim responsibility for a task: the given user is made assignee for the task. The difference with {@link #setAssignee(String, String)} is that here a check is done if the task already has a user
     * assigned to it. No check is done whether the user is known by the identity component.
     *
     * @param taskId task to claim, cannot be null.
     * @param userId user that claims the task. When userId is null the task is unclaimed, assigned to no one.
     * @throws ActivitiObjectNotFoundException                       when the task doesn't exist.
     * @throws com.je.bpm.engine.ActivitiTaskAlreadyClaimedException when the task is already claimed by another user.
     */
    void claim(String taskId, String prod, Map<String, Object> bean, String userId);

    /**
     * A shortcut to {@link #claim} with null user in order to unclaim the task
     *
     * @param taskId task to unclaim, cannot be null.
     * @throws ActivitiObjectNotFoundException when the task doesn't exist.
     */
    void unclaim(String taskId);

    /**
     * Delegates the task to another user. This means that the assignee is set and the delegation state is set to {@link com.je.bpm.engine.task.DelegationState#PENDING}. If no owner is set on the task, the owner is set to the
     * current assignee of the task.
     *
     * @param taskId The id of the task that will be delegated.
     * @param userId The id of the user that will be set as assignee.
     * @throws ActivitiObjectNotFoundException when no task exists with the given id.
     */
    void delegateTask(String taskId, String prod, Map<String, Object> bean, String userId, String comment);

    /**
     * 取消委托
     *
     * @param taskId
     */
    void cancelDelegateTask(String taskId, String prod, Map<String, Object> bean);

    /**
     * 转办
     *
     * @param taskId
     * @param userId
     */
    void transferTask(String taskId, String prod, Map<String, Object> bean, String userId, String comment);

    /**
     * 检测是否可以转办
     *
     * @param taskId
     */
    void checkTransferTask(String taskId);

    /**
     * Called when the task is successfully executed.
     *
     * @param taskId the id of the task to complete, cannot be null.
     * @throws ActivitiObjectNotFoundException when no task exists with the given id.
     * @throws ActivitiException               when this task is {@link com.je.bpm.engine.task.DelegationState#PENDING} delegation.
     */
    void complete(String taskId);

    /**
     * 循环完成，会删除当前任务，并重新创建一个任务
     *
     * @param taskId
     */
    void loop(String taskId);

    /**
     * 循环完成，会删除当前任务，并重新创建一个任务
     *
     * @param taskId
     * @param assigneeUser
     */
    void loop(String taskId, String assigneeUser);

    /**
     * Called when the task is successfully executed.
     *
     * @param taskId the id of the task to complete, cannot be null.
     * @throws ActivitiObjectNotFoundException when no task exists with the given id.
     * @throws ActivitiException               when this task is {@link com.je.bpm.engine.task.DelegationState#PENDING} delegation.
     */
    void complete(String taskId, String assigneeUser, String target, String prod, Map<String, Object> bean, String comment, String sequentials, String isJump);

    /**
     * 循环完成，会删除当前任务，并重新创建一个任务
     *
     * @param taskId
     * @param assigneeUser
     * @param variables
     */
    void loop(String taskId, String assigneeUser, Map<String, Object> variables);

    /**
     * 循环完成，会删除当前任务，并重新创建一个任务
     *
     * @param taskId
     * @param assigneeUser
     * @param variables
     * @param transientVariables
     */
    void loop(String taskId, String assigneeUser, Map<String, Object> variables, Map<String, Object> transientVariables);

    /**
     * 循环完成，会删除当前任务，并重新创建一个任务
     *
     * @param taskId
     * @param assigneeUser
     * @param variables
     * @param localScope
     */
    void loop(String taskId, String assigneeUser, Map<String, Object> variables, boolean localScope);

    /**
     * Changes the assignee of the given task to the given userId. No check is done whether the user is known by the identity component.
     *
     * @param taskId id of the task, cannot be null.
     * @param userId id of the user to use as assignee.
     * @throws ActivitiObjectNotFoundException when the task or user doesn't exist.
     */
    void setAssignee(String taskId, String userId);

    /**
     * Transfers ownership of this task to another user. No check is done whether the user is known by the identity component.
     *
     * @param taskId id of the task, cannot be null.
     * @param userId of the person that is receiving ownership.
     * @throws ActivitiObjectNotFoundException when the task or user doesn't exist.
     */
    void setOwner(String taskId, String userId);

    /**
     * Retrieves the {@link IdentityLink}s associated with the given task. Such an {@link IdentityLink} informs how a certain identity (eg. group or user) is associated with a certain task (eg. as
     * candidate, assignee, etc.)
     */
    List<IdentityLink> getIdentityLinksForTask(String taskId);

    /**
     * Convenience shorthand for {@link #addUserIdentityLink(String, String, String)}; with type {@link IdentityLinkType#CANDIDATE}
     *
     * @param taskId id of the task, cannot be null.
     * @param userId id of the user to use as candidate, cannot be null.
     * @throws ActivitiObjectNotFoundException when the task or user doesn't exist.
     */
    void addCandidateUser(String taskId, String userId);

    /**
     * Convenience shorthand for {@link #addGroupIdentityLink(String, String, String)}; with type {@link IdentityLinkType#CANDIDATE}
     *
     * @param taskId  id of the task, cannot be null.
     * @param groupId id of the group to use as candidate, cannot be null.
     * @throws ActivitiObjectNotFoundException when the task or group doesn't exist.
     */
    void addCandidateGroup(String taskId, String groupId);

    /**
     * Involves a user with a task. The type of identity link is defined by the given identityLinkType.
     *
     * @param taskId           id of the task, cannot be null.
     * @param userId           id of the user involve, cannot be null.
     * @param identityLinkType type of identityLink, cannot be null (@see {@link IdentityLinkType}).
     * @throws ActivitiObjectNotFoundException when the task or user doesn't exist.
     */
    void addUserIdentityLink(String taskId, String userId, String identityLinkType);

    /**
     * Involves a group with a task. The type of identityLink is defined by the given identityLink.
     *
     * @param taskId           id of the task, cannot be null.
     * @param groupId          id of the group to involve, cannot be null.
     * @param identityLinkType type of identity, cannot be null (@see {@link IdentityLinkType}).
     * @throws ActivitiObjectNotFoundException when the task or group doesn't exist.
     */
    void addGroupIdentityLink(String taskId, String groupId, String identityLinkType);

    /**
     * Convenience shorthand for {@link #deleteUserIdentityLink(String, String, String)}; with type {@link IdentityLinkType#CANDIDATE}
     *
     * @param taskId id of the task, cannot be null.
     * @param userId id of the user to use as candidate, cannot be null.
     * @throws ActivitiObjectNotFoundException when the task or user doesn't exist.
     */
    void deleteCandidateUser(String taskId, String userId);

    /**
     * Convenience shorthand for {@link #deleteGroupIdentityLink(String, String, String)}; with type {@link IdentityLinkType#CANDIDATE}
     *
     * @param taskId  id of the task, cannot be null.
     * @param groupId id of the group to use as candidate, cannot be null.
     * @throws ActivitiObjectNotFoundException when the task or group doesn't exist.
     */
    void deleteCandidateGroup(String taskId, String groupId);

    /**
     * Removes the association between a user and a task for the given identityLinkType.
     *
     * @param taskId           id of the task, cannot be null.
     * @param userId           id of the user involve, cannot be null.
     * @param identityLinkType type of identityLink, cannot be null (@see {@link IdentityLinkType}).
     * @throws ActivitiObjectNotFoundException when the task or user doesn't exist.
     */
    void deleteUserIdentityLink(String taskId, String userId, String identityLinkType);

    /**
     * Removes the association between a group and a task for the given identityLinkType.
     *
     * @param taskId           id of the task, cannot be null.
     * @param groupId          id of the group to involve, cannot be null.
     * @param identityLinkType type of identity, cannot be null (@see {@link IdentityLinkType}).
     * @throws ActivitiObjectNotFoundException when the task or group doesn't exist.
     */
    void deleteGroupIdentityLink(String taskId, String groupId, String identityLinkType);

    /**
     * Changes the priority of the task.
     * <p>
     * Authorization: actual owner / business admin
     *
     * @param taskId   id of the task, cannot be null.
     * @param priority the new priority for the task.
     * @throws ActivitiObjectNotFoundException when the task doesn't exist.
     */
    void setPriority(String taskId, int priority);

    /**
     * Changes the due date of the task
     *
     * @param taskId  id of the task, cannot be null.
     * @param dueDate the new due date for the task
     * @throws ActivitiException when the task doesn't exist.
     */
    void setDueDate(String taskId, Date dueDate);

    /**
     * Returns a new {@link TaskQuery} that can be used to dynamically query tasks.
     */
    TaskQuery createTaskQuery();

    /**
     * Returns a new {@link com.je.bpm.engine.query.NativeQuery} for tasks.
     */
    NativeTaskQuery createNativeTaskQuery();

    /**
     * set variable on a task. If the variable is not already existing, it will be created in the most outer scope. This means the process instance in case this task is related to an execution.
     */
    void setVariable(String taskId, String variableName, Object value);

    /**
     * set variables on a task. If the variable is not already existing, it will be created in the most outer scope. This means the process instance in case this task is related to an execution.
     */
    void setVariables(String taskId, Map<String, ? extends Object> variables);

    /**
     * set variable on a task. If the variable is not already existing, it will be created in the task.
     */
    void setVariableLocal(String taskId, String variableName, Object value);

    /**
     * set variables on a task. If the variable is not already existing, it will be created in the task.
     */
    void setVariablesLocal(String taskId, Map<String, ? extends Object> variables);

    /**
     * get a variables and search in the task scope and if available also the execution scopes.
     */
    Object getVariable(String taskId, String variableName);

    /**
     * get a variables and search in the task scope and if available also the execution scopes.
     */
    <T> T getVariable(String taskId, String variableName, Class<T> variableClass);

    /**
     * The variable. Searching for the variable is done in all scopes that are visible to the given task (including parent scopes). Returns null when no variable value is found with the given
     * name.
     *
     * @param taskId       id of task, cannot be null.
     * @param variableName name of variable, cannot be null.
     * @return the variable or null if the variable is undefined.
     * @throws ActivitiObjectNotFoundException when no execution is found for the given taskId.
     */
    VariableInstance getVariableInstance(String taskId, String variableName);

    /**
     * checks whether or not the task has a variable defined with the given name, in the task scope and if available also the execution scopes.
     */
    boolean hasVariable(String taskId, String variableName);

    /**
     * checks whether or not the task has a variable defined with the given name.
     */
    Object getVariableLocal(String taskId, String variableName);

    /**
     * checks whether or not the task has a variable defined with the given name.
     */
    <T> T getVariableLocal(String taskId, String variableName, Class<T> variableClass);

    /**
     * The variable for a task. Returns the variable when it is set for the task (and not searching parent scopes). Returns null when no variable is found with the given
     * name.
     *
     * @param taskId       id of task, cannot be null.
     * @param variableName name of variable, cannot be null.
     * @return the variable or null if the variable is undefined.
     * @throws ActivitiObjectNotFoundException when no task is found for the given taskId.
     */
    VariableInstance getVariableInstanceLocal(String taskId, String variableName);

    /**
     * checks whether or not the task has a variable defined with the given name, local task scope only.
     */
    boolean hasVariableLocal(String taskId, String variableName);

    /**
     * get all variables and search in the task scope and if available also the execution scopes. If you have many variables and you only need a few, consider using
     * {@link #getVariables(String, Collection)} for better performance.
     */
    Map<String, Object> getVariables(String taskId);

    /**
     * All variables visible from the given task scope (including parent scopes).
     *
     * @param taskId id of task, cannot be null.
     * @return the variable instances or an empty map if no such variables are found.
     * @throws ActivitiObjectNotFoundException when no task is found for the given taskId.
     */
    Map<String, VariableInstance> getVariableInstances(String taskId);

    /**
     * The variable values for all given variableNames, takes all variables into account which are visible from the given task scope (including parent scopes).
     *
     * @param taskId        id of taskId, cannot be null.
     * @param variableNames the collection of variable names that should be retrieved.
     * @return the variables or an empty map if no such variables are found.
     * @throws ActivitiObjectNotFoundException when no taskId is found for the given taskId.
     */
    Map<String, VariableInstance> getVariableInstances(String taskId, Collection<String> variableNames);

    /**
     * get all variables and search only in the task scope. If you have many task local variables and you only need a few, consider using {@link #getVariablesLocal(String, Collection)} for better
     * performance.
     */
    Map<String, Object> getVariablesLocal(String taskId);

    /**
     * get values for all given variableNames and search only in the task scope.
     */
    Map<String, Object> getVariables(String taskId, Collection<String> variableNames);

    /**
     * get a variable on a task
     */
    Map<String, Object> getVariablesLocal(String taskId, Collection<String> variableNames);

    /**
     * get all variables and search only in the task scope.
     */
    List<VariableInstance> getVariableInstancesLocalByTaskIds(Set<String> taskIds);

    /**
     * 获取退回或者取回节点名称
     *
     * @param taskId
     * @return
     */
    List<Map<String, String>> getGobackAndRetrieveNodeInfo(String taskId, String type);

    /**
     * 获取直送节点名称
     *
     * @param taskId
     * @return
     */
    Map<String, String> getDirectDeliveryName(String taskId);

    /**
     * All variable values that are defined in the task scope, without taking outer scopes into account. If you have many task local variables and you only need a few, consider using
     * {@link #getVariableInstancesLocal(String, Collection)} for better performance.
     *
     * @param taskId id of task, cannot be null.
     * @return the variables or an empty map if no such variables are found.
     * @throws ActivitiObjectNotFoundException when no task is found for the given taskId.
     */
    Map<String, VariableInstance> getVariableInstancesLocal(String taskId);

    /**
     * The variable values for all given variableNames that are defined in the given task's scope. (Does not searching parent scopes).
     *
     * @param taskId        id of taskId, cannot be null.
     * @param variableNames the collection of variable names that should be retrieved.
     * @return the variables or an empty map if no such variables are found.
     * @throws ActivitiObjectNotFoundException when no taskId is found for the given taskId.
     */
    Map<String, VariableInstance> getVariableInstancesLocal(String taskId, Collection<String> variableNames);

    /**
     * Removes the variable from the task. When the variable does not exist, nothing happens.
     */
    void removeVariable(String taskId, String variableName);

    /**
     * Removes the variable from the task (not considering parent scopes). When the variable does not exist, nothing happens.
     */
    void removeVariableLocal(String taskId, String variableName);

    /**
     * Removes all variables in the given collection from the task. Non existing variable names are simply ignored.
     */
    void removeVariables(String taskId, Collection<String> variableNames);

    /**
     * Removes all variables in the given collection from the task (not considering parent scopes). Non existing variable names are simply ignored.
     */
    void removeVariablesLocal(String taskId, Collection<String> variableNames);

    /**
     * All DataObjects visible from the given execution scope (including parent scopes).
     *
     * @param taskId id of task, cannot be null.
     * @return the DataObjects or an empty map if no such variables are found.
     * @throws ActivitiObjectNotFoundException when no task is found for the given taskId.
     */
    Map<String, DataObject> getDataObjects(String taskId);

    /**
     * All DataObjects visible from the given task scope (including parent scopes).
     *
     * @param taskId                   id of task, cannot be null.
     * @param locale                   locale the DataObject name and description should be returned in (if available).
     * @param withLocalizationFallback When true localization will fallback to more general locales if the specified locale is not found.
     * @return the DataObjects or an empty map if no DataObjects are found.
     * @throws ActivitiObjectNotFoundException when no task is found for the given task.
     */
    Map<String, DataObject> getDataObjects(String taskId, String locale, boolean withLocalizationFallback);

    /**
     * The DataObjects for all given dataObjectNames, takes all dataObjects into account which are visible from the given task scope (including parent scopes).
     *
     * @param taskId          id of task, cannot be null.
     * @param dataObjectNames the collection of DataObject names that should be retrieved.
     * @return the DataObject or an empty map if no DataObjects are found.
     * @throws ActivitiObjectNotFoundException when no task is found for the given taskId.
     */
    Map<String, DataObject> getDataObjects(String taskId, Collection<String> dataObjectNames);

    /**
     * The DataObjects for all given dataObjectNames, takes all dataObjects into account which are visible from the given task scope (including parent scopes).
     *
     * @param taskId                   id of task, cannot be null.
     * @param dataObjectNames          the collection of DataObject names that should be retrieved.
     * @param locale                   locale the DataObject name and description should be returned in (if available).
     * @param withLocalizationFallback When true localization will fallback to more general locales if the specified locale is not found.
     * @return the DataObjects or an empty map if no such dataObjects are found.
     * @throws ActivitiObjectNotFoundException when no task is found for the given task.
     */
    Map<String, DataObject> getDataObjects(String taskId, Collection<String> dataObjectNames, String locale, boolean withLocalizationFallback);

    /**
     * The DataObject. Searching for the DataObject is done in all scopes that are visible to the given task (including parent scopes). Returns null when no DataObject value is found with the given
     * name.
     *
     * @param taskId     id of task, cannot be null.
     * @param dataObject name of DataObject, cannot be null.
     * @return the DataObject or null if the variable is undefined.
     * @throws ActivitiObjectNotFoundException when no task is found for the given taskId.
     */
    DataObject getDataObject(String taskId, String dataObject);

    /**
     * The DataObject. Searching for the DataObject is done in all scopes that are visible to the given task (including parent scopes). Returns null when no DataObject value is found with the given
     * name.
     *
     * @param taskId                   id of task, cannot be null.
     * @param dataObjectName           name of DataObject, cannot be null.
     * @param locale                   locale the DataObject name and description should be returned in (if available).
     * @param withLocalizationFallback When true localization will fallback to more general locales including the default locale of the JVM if the specified locale is not found.
     * @return the DataObject or null if the DataObject is undefined.
     * @throws ActivitiObjectNotFoundException when no task is found for the given taskId.
     */
    DataObject getDataObject(String taskId, String dataObjectName, String locale, boolean withLocalizationFallback);


    /**
     * Add a comment to a task and/or process instance.
     */
    Comment addComment(String taskId, String processInstanceId, String message);

    /**
     * Add a comment to a task and/or process instance with a custom type.
     */
    Comment addComment(String taskId, String processInstanceId, String type, String message);

    /**
     * Returns an individual comment with the given id. Returns null if no comment exists with the given id.
     */
    Comment getComment(String commentId);

    /**
     * Removes all comments from the provided task and/or process instance
     */
    void deleteComments(String taskId, String processInstanceId);

    /**
     * Removes an individual comment with the given id.
     *
     * @throws ActivitiObjectNotFoundException when no comment exists with the given id.
     */
    void deleteComment(String commentId);

    /**
     * The comments related to the given task.
     */
    List<Comment> getTaskComments(String taskId);

    /**
     * The comments related to the given task of the given type.
     */
    List<Comment> getTaskComments(String taskId, String type);

    /**
     * All comments of a given type.
     */
    List<Comment> getCommentsByType(String type);

    /**
     * The all events related to the given task.
     */
    List<Event> getTaskEvents(String taskId);

    /**
     * Returns an individual event with the given id. Returns null if no event exists with the given id.
     */
    Event getEvent(String eventId);

    /**
     * The comments related to the given process instance.
     */
    List<Comment> getProcessInstanceComments(String processInstanceId);

    /**
     * The comments related to the given process instance.
     */
    List<Comment> getProcessInstanceComments(String processInstanceId, String type);

    /**
     * Add a new attachment to a task and/or a process instance and use an input stream to provide the content
     */
    Attachment createAttachment(String attachmentType, String taskId, String processInstanceId, String attachmentName, String attachmentDescription, InputStream content);

    /**
     * Add a new attachment to a task and/or a process instance and use an url as the content
     */
    Attachment createAttachment(String attachmentType, String taskId, String processInstanceId, String attachmentName, String attachmentDescription, String url);

    /**
     * Update the name and description of an attachment
     */
    void saveAttachment(Attachment attachment);

    /**
     * Retrieve a particular attachment
     */
    Attachment getAttachment(String attachmentId);

    /**
     * Retrieve stream content of a particular attachment
     */
    InputStream getAttachmentContent(String attachmentId);

    /**
     * The list of attachments associated to a task
     */
    List<Attachment> getTaskAttachments(String taskId);

    /**
     * The list of attachments associated to a process instance
     */
    List<Attachment> getProcessInstanceAttachments(String processInstanceId);

    /**
     * Delete an attachment
     */
    void deleteAttachment(String attachmentId);

    /**
     * The list of subtasks for this parent task
     */
    List<Task> getSubTasks(String parentTaskId);

    /**
     * 传阅
     *
     * @param taskId
     */
    void passRoundTask(String taskId);

    /**
     * 传阅
     *
     * @param taskId
     */
    void passRoundTask(String taskId, List<String> users, String prod, String beanId, String tableCode);

    void passRoundTask(String taskId, List<String> users, String prod, String beanId, String tableCode,String from);

    /**
     * 已阅
     *
     * @param taskId
     */
    void readPassRoundTask(String taskId, String comment);

    /**
     * 已阅
     *
     * @param taskId
     * @param userId
     */
    void readPassRoundTask(String taskId, String userId, String comment);

    /**
     * 任务延迟处理
     *
     * @param taskId
     */
    void delayTask(String taskId);

    /**
     * 任务延迟处理
     *
     * @param taskId
     */
    void delayTask(String taskId, Date nextDueTime);

    /**
     * 任务延迟处理
     *
     * @param taskId
     */
    void delayTask(String taskId, Date nextDueTime, List<String> receivers);

    /**
     * 任务延迟记录已阅
     *
     * @param delayId
     */
    void delayLogRead(String delayId);

    /**
     * 检查和执行预警
     *
     * @param processInstanceId 流程实例
     */
    void checkAndEarlyWarning(String processInstanceId);

    /**
     * 预警信息已读
     *
     * @param earlyWarningId
     */
    void earlyWarningRead(String earlyWarningId);

    /**
     * 催办
     *
     * @param reminderMethod   催办方式
     * @param personBeingUrged 催办人
     * @param urgentContent    催办内容
     * @param ccUser           抄送人
     * @param ccContent        抄送内容
     * @param taskId           任务id
     * @param currentNodeId    当前节点id
     * @param funcCode         功能code
     */
    void urgeTask(List<String> reminderMethod, List<Map<String, String>> personBeingUrged, String urgentContent,
                  List<Map<String, String>> ccUser, String ccContent, String taskId, String currentNodeId, String funcCode);

    /**
     * 设置日志已读
     *
     * @param urgeLogId
     */
    void readUrgeLog(String urgeLogId);

    /**
     * 跳转
     *
     * @param currentTaskId
     * @param targetDefinitionKey
     * @param variables
     */
    void jump(String currentTaskId, String targetDefinitionKey, Map<String, Object> variables);

    /**
     * 取回
     *
     * @param taskId
     */
    void retrieveTask(String taskId, String prod, Map<String, Object> bean, String beanId);

    /**
     * 取回
     *
     * @param taskId
     */
    void retrieveTask(String taskId, String prod, Map<String, Object> bean, String comment, String beanId);

    /**
     * 退回
     *
     * @param taskId
     */
    void gobackTask(String taskId);

    /**
     * 退回
     *
     * @param taskId
     */
    void gobackTask(String taskId, String prod, Map<String, Object> bean, String comment);

    /**
     * 直送
     *
     * @param taskId
     */
    void directComplete(String taskId, Map<String, Object> bean, String prod);

    /**
     * 直送
     *
     * @param taskId
     */
    void directComplete(String taskId, String comment, Map<String, Object> bean, String prod);

    /**
     * 驳回
     *
     * @param taskId
     */
    void dismissTask(String taskId, String definitionKey);

    /**
     * 驳回
     *
     * @param taskId
     */
    void dismissTask(String taskId, String definitionKey, String comment, Map<String, Object> bean, String prod);

    /**
     * 获取当前流程实例任务
     *
     * @param processInstanceId
     * @return
     */
    Map<String, Object> getCurrentTask(String processInstanceId);

    /**
     * 通过
     *
     * @param taskId
     * @param comment
     */
    void pass(String taskId, String prod, Map<String, Object> bean, String comment);

    /**
     * 弃权
     *
     * @param taskId
     * @param comment
     */
    void abstain(String taskId, String prod, Map<String, Object> bean, String comment);

    /**
     * 否决
     *
     * @param taskId
     * @param comment
     */
    void veto(String taskId, String prod, Map<String, Object> bean, String comment);

    /**
     * 会签-加签
     *
     * @param assignee
     * @param taskId
     */
    void countersignedAddSignature(String assignee, String taskId);

    /**
     * 会签-调整人员
     *
     * @param assignee
     * @param taskId
     */
    void personnelAdjustments(String assignee, String taskId);

    /**
     * 会签-减签
     *
     * @param assignee
     * @param taskId
     */
    void countersignedVisaReduction(String assignee, String taskId);

    /**
     * 会签-改签
     *
     * @param assignee
     * @param opinionType
     */
    void countersignedRebook(String assignee, String taskId, String comment, ActivitiCountersignedOpinionType opinionType);

    /**
     * 会签-更换负责人
     *
     * @param assignee
     */
    void countersignedChangePerson(String assignee, String prod, Map<String, Object> bean, String taskId);

    List<String> getCounterSignStaff(String taskId);

    String getRootExecutionIdByTaskId(String taskId);

    List<TaskEntity> getTaskIdByRootExecutionId(String rootExecutionId);

    /**
     * 获取会签可操作人信息
     *
     * @param taskId
     * @return
     */
    Map<String, Object> getCounterSignerOperationalUsers(String taskId);

    /**
     * 获取人员
     *
     * @param kaiteBaseUserTask
     * @return
     */
    Object getAssignment(Boolean addOwn, Boolean multiple, String pdid, KaiteBaseUserTask kaiteBaseUserTask,
                         String taskId, String prod, Map<String, Object> bean, FlowNode flowNode);

    /**
     * 获取人员名称
     *
     * @param userId
     * @return
     */
    String getUserNameByUserId(String userId);

    /**
     * 判断当前登录人是否在节点可处理人中
     *
     * @param pdid
     * @param kaiteBaseUserTask
     * @param taskId
     * @param prod
     * @param bean
     * @return
     */
    Boolean assignerContainsCurrentUser(String pdid, KaiteBaseUserTask kaiteBaseUserTask, String taskId,
                                        String prod, Map<String, Object> bean);

    /**
     * 获取传阅人员信息
     *
     * @param list
     * @param taskId
     * @param prod
     * @param bean
     * @return
     */
    Object getCirculatedAssignment(String taskId, String prod, Map<String, Object> bean);

}
